bitkeeper revision 1.1162 (420b71f6yarVsHEUH8wBvGFgIVSTBQ)
authorsos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Thu, 10 Feb 2005 14:38:46 +0000 (14:38 +0000)
committersos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Thu, 10 Feb 2005 14:38:46 +0000 (14:38 +0000)
Re-sanify after merge.

.rootkeys
xen/Rules.mk
xen/arch/x86/Makefile
xen/arch/x86/cdb.c [new file with mode: 0644]
xen/arch/x86/x86_32/cdb_trap.S [new file with mode: 0644]
xen/arch/x86/x86_32/xdb_trap.S [deleted file]
xen/arch/x86/xdb.c [deleted file]
xen/common/domain.c
xen/common/keyhandler.c
xen/drivers/char/console.c
xen/include/asm-x86/debugger.h

index ab7a2c49ce3fa025402cc6f334c496163b0d9bf3..8c6ec110cbe84da0ed677b7bb1a60126d12d2010 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 3ddb79c4yGZ7_22QAFFwPzqP4NSHwA xen/arch/x86/boot/mkelf32.c
 3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/x86_32.S
 40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/x86/boot/x86_64.S
+4107c15e-VmEcLsE-7JCXZaabI8C7A xen/arch/x86/cdb.c
 3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c
 40e34414WiQO4h2m3tcpaCPn7SyYyg xen/arch/x86/dom0_ops.c
 3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/domain.c
 41f97ef5139vN42cOYHfX_Ac8WOOjA xen/arch/x86/vmx_platform.c
 41c0c4128URE0dxcO15JME_MuKBPfg xen/arch/x86/vmx_vmcs.c
 419cbedeQDg8IrO3izo3o5rQNlo0kQ xen/arch/x86/x86_32/asm-offsets.c
+4107c15e_NqNYew2EXroXz2mgTAMWQ xen/arch/x86/x86_32/cdb_trap.S
 4202391dkvdTZ8GhWXe3Gqf9EOgWXg xen/arch/x86/x86_32/domain_build.c
 3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/x86_32/domain_page.c
 3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/x86_32/entry.S
 40f92331jfOlE7MfKwpdkEb1CEf23g xen/arch/x86/x86_32/seg_fixup.c
 42000d3ckiFc1qxa4AWqsd0t3lxuyw xen/arch/x86/x86_32/traps.c
 3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c
-4107c15e_NqNYew2EXroXz2mgTAMWQ xen/arch/x86/x86_32/xdb_trap.S
 3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds
 41bf1717Ty3hwN3E9swdu8QfnvGqww xen/arch/x86/x86_64/asm-offsets.c
 4202391dA91ZovYX9d_5zJi9yGvLoQ xen/arch/x86/x86_64/domain_build.c
 42000d3cMb8o1WuFBXC07c8i3lPZBw xen/arch/x86/x86_64/traps.c
 40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c
 40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds
-4107c15e-VmEcLsE-7JCXZaabI8C7A xen/arch/x86/xdb.c
 3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
 3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c
 3ddb79bdLX_P6iB7ILiblRLWvebapg xen/common/dom0_ops.c
index 300efbf5810253cdd8cb7339c44defdc52e5a16b..f8def0ec885b3d5674abca63858c3f7bc7d7a575 100644 (file)
@@ -5,6 +5,7 @@ debugger    ?= n
 perfc       ?= n
 trace       ?= n
 optimize    ?= y
+crash_debug ?= n
 
 # Currently supported architectures: x86_32, x86_64
 COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
@@ -54,8 +55,11 @@ else
 CFLAGS += -DVERBOSE
 endif
 
-ifeq ($(gdb_stub),y)
-CFLAGS += -g
+ifeq ($(crash_debug),y)
+CFLAGS += -g -DCRASH_DEBUG
+ifeq ($(debugger),y)
+error Crash debugger conflicts with PDB
+endif
 endif
 
 ifeq ($(perfc),y)
index c2a48624e02685790e7ac73ceb1dadf01d883412..d0750ac4002b663e11397ba86af2cd8029b31353 100644 (file)
@@ -11,6 +11,10 @@ ifneq ($(TARGET_SUBARCH),x86_32)
 OBJS := $(patsubst vmx%.o,,$(OBJS))
 endif
 
+ifneq ($(crash_debug),y)
+OBJS := $(subst cdb%.o,,$(OBJS))
+endif
+
 default: $(TARGET)
 
 $(TARGET): $(TARGET)-syms boot/mkelf32
diff --git a/xen/arch/x86/cdb.c b/xen/arch/x86/cdb.c
new file mode 100644 (file)
index 0000000..db0e9b0
--- /dev/null
@@ -0,0 +1,357 @@
+/* Simple hacked-up version of pdb for use in post-mortem debugging of
+   Xen and domain 0. This should be a little cleaner, hopefully.  Note
+   that we can't share a serial line with PDB. */
+/* We try to avoid assuming much about what the rest of the system is
+   doing.  In particular, dynamic memory allocation is out of the
+   question. */
+#include <xen/lib.h>
+#include <asm/uaccess.h>
+#include <xen/serial.h>
+#include <asm/irq.h>
+#include <xen/spinlock.h>
+#include <asm/debugger.h>
+
+/* Printk isn't particularly safe just after we've trapped to the
+   debugger. so avoid it. */
+#define dbg_printk(...)
+
+static unsigned char opt_cdb[30] = "none";
+string_param("cdb", opt_cdb);
+
+struct xendbg_context {
+       int serhnd;
+       u8 reply_csum;
+       int currently_attached:1;
+};
+
+static void
+xendbg_put_char(u8 data, struct xendbg_context *ctx)
+{
+       ctx->reply_csum += data;
+       serial_putc(ctx->serhnd, data);
+}
+
+static int
+hex_char_val(unsigned char c)
+{
+       if (c >= '0' && c <= '9')
+               return c - '0';
+       else if (c >= 'a' && c <= 'f')
+               return c - 'a' + 10;
+       else if (c >= 'A' && c <= 'F')
+               return c - 'A' + 10;
+       else
+               BUG();
+       return -1;
+}
+
+/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
+/* Does not acknowledge. */
+static int
+attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
+{
+       int count;
+       u8 csum;
+       u8 received_csum;
+       u8 ch;
+
+       /* Skip over everything up to the first '$' */
+       while ((ch = irq_serial_getc(ctx->serhnd)) != '$')
+               ;
+       csum = 0;
+       for (count = 0; count < 4096; count++) {
+               ch = irq_serial_getc(ctx->serhnd);
+               if (ch == '#')
+                       break;
+               recv_buf[count] = ch;
+               csum += ch;
+       }
+       if (count == 4096) {
+               dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
+               return -1;
+       }
+       recv_buf[count] = 0;
+       received_csum = hex_char_val(irq_serial_getc(ctx->serhnd)) * 16 +
+               hex_char_val(irq_serial_getc(ctx->serhnd));
+       if (received_csum == csum) {
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+/* Send a string of bytes to the debugger. */
+static void
+xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
+{
+       int x;
+       for (x = 0; x < count; x++)
+               xendbg_put_char(buf[x], ctx);
+}
+
+/* Receive a command, discarding up to ten packets with csum
+ * errors.  Acknowledges all received packets. */
+static int
+receive_command(char *recv_buf, struct xendbg_context *ctx)
+{
+       int r;
+       int count;
+
+       count = 0;
+       do {
+               r = attempt_receive_packet(recv_buf, ctx);
+               if (r < 0)
+                       xendbg_put_char('-', ctx);
+               else
+                       xendbg_put_char('+', ctx);
+               count++;
+       } while (r < 0 && count < 10);
+       return r;
+}
+
+static void
+xendbg_start_reply(struct xendbg_context *ctx)
+{
+       xendbg_put_char('$', ctx);
+       ctx->reply_csum = 0;
+}
+
+/* Return 0 if the reply was successfully received, !0 otherwise. */
+static int
+xendbg_finish_reply(struct xendbg_context *ctx)
+{
+       char ch;
+       char buf[3];
+
+       sprintf(buf, "%.02x\n", ctx->reply_csum);
+
+       xendbg_put_char('#', ctx);
+       xendbg_send(buf, 2, ctx);
+
+       ch = irq_serial_getc(ctx->serhnd);
+       if (ch == '+')
+               return 0;
+       else
+               return 1;
+}
+
+/* Swap the order of the bytes in a work. */
+static inline unsigned
+bswab32(unsigned val)
+{
+       return (((val >> 0) & 0xff) << 24) |
+               (((val >> 8) & 0xff) << 16) |
+               (((val >> 16) & 0xff) << 8) |
+               (((val >> 24) & 0xff) << 0);
+}
+
+static int
+handle_memory_read_command(unsigned long addr, unsigned long length,
+                          struct xendbg_context *ctx)
+{
+       int x;
+       unsigned char val;
+       int r;
+       char buf[2];
+
+       dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
+                  length);
+       xendbg_start_reply(ctx);
+       for (x = 0; x < length; x++) {
+               r = __copy_from_user(&val, (void *)(addr + x), 1);
+               if (r != 0) {
+                       dbg_printk("Error reading from %lx.\n", addr + x);
+                       break;
+               }
+               sprintf(buf, "%.02x", val);
+               xendbg_send(buf, 2, ctx);
+       }
+       if (x == 0)
+               xendbg_send("E05", 3, ctx);
+       dbg_printk("Read done.\n");
+       return xendbg_finish_reply(ctx);
+}
+
+static int
+xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
+{
+       xendbg_start_reply(ctx);
+       xendbg_send(buf, strlen(buf), ctx);
+       return xendbg_finish_reply(ctx);
+}
+
+static int
+handle_register_read_command(struct xen_regs *regs, struct xendbg_context *ctx)
+{
+       char buf[121];
+
+       sprintf(buf,
+               "%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
+               bswab32(regs->eax),
+               bswab32(regs->ecx),
+               bswab32(regs->edx),
+               bswab32(regs->ebx),
+               bswab32(regs->esp),
+               bswab32(regs->ebp),
+               bswab32(regs->esi),
+               bswab32(regs->edi),
+               bswab32(regs->eip),
+               bswab32(regs->eflags),
+               bswab32(regs->cs),
+               bswab32(regs->ss),
+               bswab32(regs->es),
+               bswab32(regs->fs),
+               bswab32(regs->gs));
+       return xendbg_send_reply(buf, ctx);
+}
+
+static int
+process_command(char *received_packet, struct xen_regs *regs,
+               struct xendbg_context *ctx)
+{
+       char *ptr;
+       unsigned long addr, length;
+       int retry;
+       int counter;
+       int resume = 0;
+
+       /* Repeat until gdb acks the reply */
+       counter = 0;
+       do {
+               switch (received_packet[0]) {
+               case 'g': /* Read registers */
+                       retry = handle_register_read_command(regs, ctx);
+                       break;
+               case 'm': /* Read memory */
+                       addr = simple_strtoul(received_packet + 1, &ptr, 16);
+                       if (ptr == received_packet + 1 ||
+                           ptr[0] != ',') {
+                               xendbg_send_reply("E03", ctx);
+                               return 0;
+                       }
+                       length = simple_strtoul(ptr + 1, &ptr, 16);
+                       if (ptr[0] != 0) {
+                               xendbg_send_reply("E04", ctx);
+                               return 0;
+                       }
+                       retry =
+                               handle_memory_read_command(addr,
+                                                          length,
+                                                          ctx);
+                       break;
+               case 'G': /* Write registers */
+               case 'M': /* Write memory */
+                       retry = xendbg_send_reply("E02", ctx);
+                       break;
+               case 'D':
+                       resume = 1;
+                       ctx->currently_attached = 0;
+                       retry = xendbg_send_reply("", ctx);
+                       break;
+               case 'c': /* Resume at current address */
+                       ctx->currently_attached = 1;
+                       resume = 1;
+                       retry = 0;
+                       break;
+               case 'Z': /* We need to claim to support these or gdb
+                            won't let you continue the process. */
+               case 'z':
+                       retry = xendbg_send_reply("OK", ctx);
+                       break;
+
+               case 's': /* Single step */
+               case '?':
+                       retry = xendbg_send_reply("S01", ctx);
+                       break;
+               default:
+                       retry = xendbg_send_reply("", ctx);
+                       break;
+               }
+               counter++;
+       } while (retry == 1 && counter < 10);
+       if (retry) {
+               dbg_printk("WARNING: gdb disappeared when we were trying to send it a reply.\n");
+               return 1;
+       }
+       return resume;
+}
+
+static struct xendbg_context
+xdb_ctx = {
+       serhnd : -1
+};
+
+void
+__trap_to_cdb(struct xen_regs *regs)
+{
+       int resume = 0;
+       int r;
+       static atomic_t xendbg_running = ATOMIC_INIT(1);
+       static char recv_buf[4096];
+       unsigned flags;
+
+       if (xdb_ctx.serhnd < 0) {
+               dbg_printk("Debugger not ready yet.\n");
+               return;
+       }
+
+       /* Try to make things a little more stable by disabling
+          interrupts while we're here. */
+       local_irq_save(flags);
+
+       /* We rely on our caller to ensure we're only on one processor
+        * at a time... We should probably panic here, but given that
+        * we're a debugger we should probably be a little tolerant of
+        * things going wrong. */
+       /* We don't want to use a spin lock here, because we're doing
+          two distinct things:
+
+          1 -- we don't want to run on more than one processor at a time,
+               and
+          2 -- we want to do something sensible if we re-enter ourselves.
+
+          Spin locks are good for 1, but useless for 2. */
+       if (!atomic_dec_and_test(&xendbg_running)) {
+               printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
+               atomic_inc(&xendbg_running);
+               local_irq_restore(flags);
+               return;
+       }
+
+       /* Shouldn't really do this, but otherwise we stop for no
+          obvious reason, which is Bad */
+       printk("Waiting for GDB to attach to XenDBG\n");
+
+       /* If gdb is already attached, tell it we've stopped again. */
+       if (xdb_ctx.currently_attached) {
+               do {
+                       r = xendbg_send_reply("S01", &xdb_ctx);
+               } while (r != 0);
+       }
+
+       while (resume == 0) {
+               r = receive_command(recv_buf, &xdb_ctx);
+               if (r < 0) {
+                       dbg_printk("GDB disappeared, trying to resume Xen...\n");
+                       resume = 1;
+               } else
+                       resume = process_command(recv_buf, regs, &xdb_ctx);
+       }
+       atomic_inc(&xendbg_running);
+       local_irq_restore(flags);
+}
+
+void
+initialize_xendbg(void)
+{
+       if (!strcmp(opt_cdb, "none"))
+               return;
+       xdb_ctx.serhnd = parse_serial_handle(opt_cdb);
+       if (xdb_ctx.serhnd == -1)
+               panic("Can't parse %s as CDB serial info.\n", opt_cdb);
+
+       /* Acknowledge any spurious GDB packets. */
+       xendbg_put_char('+', &xdb_ctx);
+
+       printk("Xendbg initialised.\n");
+}
diff --git a/xen/arch/x86/x86_32/cdb_trap.S b/xen/arch/x86/x86_32/cdb_trap.S
new file mode 100644 (file)
index 0000000..dfae4c5
--- /dev/null
@@ -0,0 +1,36 @@
+.global cdb_trap
+.extern __trap_to_cdb
+       
+#define SAVE_ALL_NOSEGREGS \
+       pushw $0;  \
+        pushw %gs; \
+       pushw $0;  \
+        pushw %fs; \
+       pushw $0;  \
+        pushw %es; \
+       pushw $0;  \
+        pushw %ds; \
+        pushl %eax; \
+        pushl %ebp; \
+        pushl %edi; \
+        pushl %esi; \
+        pushl %edx; \
+        pushl %ecx; \
+        pushl %ebx;
+
+       // Save the register state and call __trap_to_cdb
+cdb_trap:
+       pushw $0
+       pushw %ss
+       pushl %esp //We'll fix this up later, in __trap_to_cdb, by adding 8
+       pushf
+       pushw $0
+       pushw %cs
+       pushl 16(%esp)
+1:     pushl $0                // Orig_eax
+       SAVE_ALL_NOSEGREGS
+       pushl %esp
+       call __trap_to_cdb
+       add $72, %esp
+       xorl %eax, %eax
+       ret
diff --git a/xen/arch/x86/x86_32/xdb_trap.S b/xen/arch/x86/x86_32/xdb_trap.S
deleted file mode 100644 (file)
index 262c6db..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-.global trap_to_xendbg
-.extern __trap_to_xendbg
-       
-#define SAVE_ALL_NOSEGREGS \
-       pushw $0;  \
-        pushw %gs; \
-       pushw $0;  \
-        pushw %fs; \
-       pushw $0;  \
-        pushw %es; \
-       pushw $0;  \
-        pushw %ds; \
-        pushl %eax; \
-        pushl %ebp; \
-        pushl %edi; \
-        pushl %esi; \
-        pushl %edx; \
-        pushl %ecx; \
-        pushl %ebx;
-
-       // Save the register state and call __trap_to_xendbg 
-trap_to_xendbg:
-       pushw $0
-       pushw %ss
-       pushl %esp //We'll fix this up later, in __trap_to_xendbg, by adding 8
-       pushf
-       pushw $0
-       pushw %cs
-       pushl 16(%esp)
-1:     pushl $0                // Orig_eax
-       SAVE_ALL_NOSEGREGS
-       pushl %esp
-       call __trap_to_xendbg
-       add $72, %esp
-       ret
diff --git a/xen/arch/x86/xdb.c b/xen/arch/x86/xdb.c
deleted file mode 100644 (file)
index b7bf770..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/* Simple hacked-up version of pdb for us in post-mortem debugging of
-   Xen and domain 0. This should be a little cleaner, hopefully.  Note
-   that we can't share a serial line with PDB. */
-#include <xen/lib.h>
-#include <asm/uaccess.h>
-#include <xen/serial.h>
-#include <asm/irq.h>
-#include <xen/spinlock.h>
-
-/* Printk isn't particularly safe just after we've trapped to the
-   debugger. so avoid it. */
-#define dbg_printk(...)
-
-struct xendbg_context {
-       int serhnd;
-       u8 reply_csum;
-       int currently_attached:1;
-};
-
-static void
-xendbg_put_char(u8 data, struct xendbg_context *ctx)
-{
-       ctx->reply_csum += data;
-       serial_putc(ctx->serhnd, data);
-}
-
-static u8
-xendbg_get_char(struct xendbg_context *ctx)
-{
-       u8 ch;
-       extern unsigned char __serial_getc(int handle);
-       ch = __serial_getc(ctx->serhnd);
-       return ch;
-}
-
-static int
-hex_char_val(unsigned char c)
-{
-       if (c >= '0' && c <= '9')
-               return c - '0';
-       else if (c >= 'a' && c <= 'f')
-               return c - 'a' + 10;
-       else if (c >= 'A' && c <= 'F')
-               return c - 'A' + 10;
-       else
-               BUG();
-       return -1;
-}
-
-/* Receive a command.  Returns -1 on csum error, 0 otherwise. */
-/* Does not acknowledge. */
-static int
-attempt_receive_packet(char *recv_buf, struct xendbg_context *ctx)
-{
-       int count;
-       u8 csum;
-       u8 received_csum;
-       u8 ch;
-
-       /* Skip over everything up to the first '$' */
-       while ((ch = xendbg_get_char(ctx)) != '$')
-               ;
-       csum = 0;
-       for (count = 0; count < 4096; count++) {
-               ch = xendbg_get_char(ctx);
-               if (ch == '#')
-                       break;
-               recv_buf[count] = ch;
-               csum += ch;
-       }
-       if (count == 4096) {
-               dbg_printk("WARNING: GDB sent a stupidly big packet.\n");
-               return -1;
-       }
-       recv_buf[count] = 0;
-       received_csum = hex_char_val(xendbg_get_char(ctx)) * 16 +
-               hex_char_val(xendbg_get_char(ctx));
-       if (received_csum == csum) {
-               return 0;
-       } else {
-               return -1;
-       }
-}
-
-/* Send a string of bytes to the debugger. */
-static void
-xendbg_send(const char *buf, int count, struct xendbg_context *ctx)
-{
-       int x;
-       for (x = 0; x < count; x++)
-               xendbg_put_char(buf[x], ctx);
-}
-
-/* Receive a command, discarding up to ten packets with csum
- * errors.  Acknowledges all received packets. */
-static int
-receive_command(char *recv_buf, struct xendbg_context *ctx)
-{
-       int r;
-       int count;
-
-       count = 0;
-       do {
-               r = attempt_receive_packet(recv_buf, ctx);
-               if (r < 0)
-                       xendbg_put_char('-', ctx);
-               else
-                       xendbg_put_char('+', ctx);
-               count++;
-       } while (r < 0 && count < 10);
-       return r;
-}
-
-static void
-xendbg_start_reply(struct xendbg_context *ctx)
-{
-       xendbg_put_char('$', ctx);
-       ctx->reply_csum = 0;
-}
-
-/* Return 0 if the reply was successfully received, !0 otherwise. */
-static int
-xendbg_finish_reply(struct xendbg_context *ctx)
-{
-       char ch;
-       char buf[3];
-
-       sprintf(buf, "%.02x\n", ctx->reply_csum);
-
-       xendbg_put_char('#', ctx);
-       xendbg_send(buf, 2, ctx);
-
-       ch = xendbg_get_char(ctx);
-       if (ch == '+')
-               return 0;
-       else
-               return 1;
-}
-
-/* Swap the order of the bytes in a work. */
-static inline unsigned
-bswab32(unsigned val)
-{
-       return (((val >> 0) & 0xff) << 24) |
-               (((val >> 8) & 0xff) << 16) |
-               (((val >> 16) & 0xff) << 8) |
-               (((val >> 24) & 0xff) << 0);
-}
-
-static int
-handle_memory_read_command(unsigned long addr, unsigned long length,
-                          struct xendbg_context *ctx)
-{
-       int x;
-       unsigned char val;
-       int r;
-       unsigned old_s_limit;
-       char buf[2];
-
-       dbg_printk("Memory read starting at %lx, length %lx.\n", addr,
-                  length);
-       old_s_limit = current->addr_limit.seg;
-       current->addr_limit.seg = ~0;
-       xendbg_start_reply(ctx);
-       for (x = 0; x < length; x++) {
-               r = copy_from_user(&val, (void *)(addr + x), 1);
-               if (r != 0) {
-                       dbg_printk("Error reading from %lx.\n", addr + x);
-                       break;
-               }
-               sprintf(buf, "%.02x", val);
-               xendbg_send(buf, 2, ctx);
-       }
-       if (x == 0)
-               xendbg_send("E05", 3, ctx);
-       dbg_printk("Read done.\n");
-       current->addr_limit.seg = old_s_limit;
-       return xendbg_finish_reply(ctx);
-}
-
-static int
-xendbg_send_reply(const char *buf, struct xendbg_context *ctx)
-{
-       xendbg_start_reply(ctx);
-       xendbg_send(buf, strlen(buf), ctx);
-       return xendbg_finish_reply(ctx);
-}
-
-static int
-handle_register_read_command(struct pt_regs *regs, struct xendbg_context *ctx)
-{
-       char buf[121];
-
-       sprintf(buf,
-               "%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x%.08x",
-               bswab32(regs->eax),
-               bswab32(regs->ecx),
-               bswab32(regs->edx),
-               bswab32(regs->ebx),
-               bswab32(regs->esp),
-               bswab32(regs->ebp),
-               bswab32(regs->esi),
-               bswab32(regs->edi),
-               bswab32(regs->eip),
-               bswab32(regs->eflags),
-               bswab32(regs->xcs),
-               bswab32(regs->xss),
-               bswab32(regs->xes),
-               bswab32(regs->xfs),
-               bswab32(regs->xgs));
-       return xendbg_send_reply(buf, ctx);
-}
-
-static int
-process_command(char *received_packet, struct pt_regs *regs,
-               struct xendbg_context *ctx)
-{
-       char *ptr;
-       unsigned long addr, length;
-       int retry;
-       int counter;
-       int resume = 0;
-
-       /* Repeat until gdb acks the reply */
-       counter = 0;
-       do {
-               switch (received_packet[0]) {
-               case 'g': /* Read registers */
-                       retry = handle_register_read_command(regs, ctx);
-                       break;
-               case 'm': /* Read memory */
-                       addr = simple_strtoul(received_packet + 1, &ptr, 16);
-                       if (ptr == received_packet + 1 ||
-                           ptr[0] != ',') {
-                               xendbg_send_reply("E03", ctx);
-                               return 0;
-                       }
-                       length = simple_strtoul(ptr + 1, &ptr, 16);
-                       if (ptr[0] != 0) {
-                               xendbg_send_reply("E04", ctx);
-                               return 0;
-                       }
-                       retry =
-                               handle_memory_read_command(addr,
-                                                          length,
-                                                          ctx);
-                       break;
-               case 'G': /* Write registers */
-               case 'M': /* Write memory */
-                       retry = xendbg_send_reply("E02", ctx);
-                       break;
-               case 'D':
-                       resume = 1;
-                       ctx->currently_attached = 0;
-                       retry = xendbg_send_reply("", ctx);
-                       break;
-               case 'c': /* Resume at current address */
-                       ctx->currently_attached = 1;
-                       resume = 1;
-                       retry = 0;
-                       break;
-               case 'Z': /* We need to claim to support these or gdb
-                            won't let you continue the process. */
-               case 'z':
-                       retry = xendbg_send_reply("OK", ctx);
-                       break;
-
-               case 's': /* Single step */
-               case '?':
-                       retry = xendbg_send_reply("S01", ctx);
-                       break;
-               default:
-                       retry = xendbg_send_reply("", ctx);
-                       break;
-               }
-               counter++;
-       } while (retry == 1 && counter < 10);
-       if (retry) {
-               dbg_printk("WARNING: gdb disappeared when we were trying to send it a reply.\n");
-               return 1;
-       }
-       return resume;
-}
-
-static struct xendbg_context
-xdb_ctx = {
-       serhnd : -1
-};
-
-void
-__trap_to_xendbg(struct pt_regs *regs)
-{
-       int resume = 0;
-       int r;
-       static int xendbg_running;
-       static char recv_buf[4096];
-       unsigned flags;
-
-       if (xdb_ctx.serhnd < 0) {
-               dbg_printk("Debugger not ready yet.\n");
-               return;
-       }
-       /* We rely on our caller to ensure we're only on one processor
-        * at a time... We should probably panic here, but given that
-        * we're a debugger we should probably be a little tolerant of
-        * things going wrong. */
-       if (xendbg_running) {
-               dbg_printk("WARNING WARNING WARNING: Avoiding recursive xendbg.\n");
-               return;
-       }
-       xendbg_running = 1;
-
-       /* Shouldn't really do this, but otherwise we stop for no
-          obvious reason, which is Bad */
-       printk("Waiting for GDB to attach to XenDBG\n");
-
-       /* Try to make things a little more stable by disabling
-          interrupts while we're here. */
-       local_irq_save(flags);
-
-       /* If gdb is already attached, tell it we've stopped again. */
-       if (xdb_ctx.currently_attached) {
-               do {
-                       r = xendbg_send_reply("S01", &xdb_ctx);
-               } while (r != 0);
-       }
-
-       while (resume == 0) {
-               r = receive_command(recv_buf, &xdb_ctx);
-               if (r < 0) {
-                       dbg_printk("GDB disappeared, trying to resume Xen...\n");
-                       resume = 1;
-               } else
-                       resume = process_command(recv_buf, regs, &xdb_ctx);
-       }
-       xendbg_running = 0;
-       local_irq_restore(flags);
-}
-
-void
-initialize_xendbg(void)
-{
-       extern char opt_xendbg[];
-
-       if (!strcmp(opt_xendbg, "none"))
-               return;
-       xdb_ctx.serhnd = parse_serial_handle(opt_xendbg);
-       if (xdb_ctx.serhnd == -1)
-               panic("Can't parse %s as XDB serial info.\n", opt_xendbg);
-
-       /* Acknowledge any spurious GDB packets. */
-       xendbg_put_char('+', &xdb_ctx);
-
-       printk("Xendbg initialised.\n");
-}
index 394e9804be5912a88fa3b12029a175cf3b80c00d..081c68820f71e34cbe7199c84563aeadff84da10 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/shadow.h>
 #include <public/dom0_ops.h>
 #include <asm/domain_page.h>
+#include <asm/debugger.h>
 
 /* Both these structures are protected by the domlist_lock. */
 rwlock_t domlist_lock = RW_LOCK_UNLOCKED;
@@ -172,7 +173,7 @@ void domain_shutdown(u8 reason)
         extern void machine_restart(char *);
         extern void machine_halt(void);
 
-       trap_to_xendbg();
+        debugger_trap_immediate();
 
         if ( reason == 0 ) 
         {
index 5b5cd662ef3e70805a5eed1257692bdbe5c58cba..571b76e59bedc9dded569eac85881c0820233b19 100644 (file)
@@ -10,6 +10,7 @@
 #include <xen/serial.h>
 #include <xen/sched.h>
 #include <xen/softirq.h>
+#include <asm/debugger.h>
 
 #define KEY_MAX 256
 #define STR_MAX  64
@@ -146,13 +147,12 @@ extern void perfc_printall(unsigned char key);
 extern void perfc_reset(unsigned char key);
 #endif
 
-void do_debug_key(unsigned char key, void *dev_id, struct pt_regs *regs)
+void do_debug_key(unsigned char key, struct xen_regs *regs)
 {
-    extern void trap_to_xendbg(void);
-    trap_to_xendbg();
+    debugger_trap_fatal(0xf001, regs);
     asm volatile ("nop"); /* Prevent the compiler doing tail call
-                            optimisation, as that confuses xendbg a
-                            bit. */
+                             optimisation, as that confuses xendbg a
+                             bit. */
 }
 
 void initialize_keytable(void)
@@ -185,5 +185,5 @@ void initialize_keytable(void)
     register_keyhandler(
         'P', perfc_reset,    "reset performance counters"); 
 #endif
-    add_key_handler('%', do_debug_key,   "Trap to xendbg");
+    register_irq_keyhandler('%', do_debug_key,   "Trap to xendbg");
 }
index a94714bcb8eeafa8d4a4844a93964ad4115cf0a7..c0a9dd248ed019c7a90798fb81ec8e30440bee4e 100644 (file)
@@ -20,6 +20,7 @@
 #include <xen/keyhandler.h>
 #include <asm/uaccess.h>
 #include <asm/mm.h>
+#include <asm/debugger.h>
 
 /* opt_console: comma-separated list of console outputs. */
 static unsigned char opt_console[30] = OPT_CONSOLE_STR;
@@ -497,7 +498,7 @@ void panic(const char *fmt, ...)
     (void)vsnprintf(buf, sizeof(buf), fmt, args);
     va_end(args);
 
-    trap_to_xendbg();
+    debugger_trap_immediate();
 
     /* Spit out multiline message in one go. */
     spin_lock_irqsave(&console_lock, flags);
index d44b2d5e620d75f4cd23f56218a61c5a38cd3843..74e8a82ef50d67012e62505c3b2f2213845b7f19 100644 (file)
@@ -93,6 +93,16 @@ static inline int debugger_trap_fatal(
     return ret;
 }
 
+#define debugger_trap_immediate() ()
+
+#elif defined(CRASH_DEBUG)
+
+extern void cdb_trap(void);
+extern void __trap_to_cdb(struct xen_regs *);
+#define debugger_trap_entry(_v, _r) (0)
+#define debugger_trap_fatal(_v, _r) (__trap_to_cdb(_r), 0)
+#define debugger_trap_immediate() (cdb_trap())
+
 #elif 0
 
 extern int kdb_trap(int, int, struct xen_regs *);
@@ -113,6 +123,7 @@ static inline int debugger_trap_fatal(
 
 #define debugger_trap_entry(_v, _r) (0)
 #define debugger_trap_fatal(_v, _r) (0)
+#define debugger_trap_immediate() ()
 
 #endif